package main

import (
	"log"
	"math/rand"
)

//缓冲机制
// 多个goroutine 使用select 进行扇入
// 退出通知机制
func main() {
	done := make(chan struct{})

	// 启动生成器
	ch := demo1(done)

	// 取出生成好的 数据
	for i := 0; i < 100; i++ {
		log.Println("随机数", <-ch)
	}

	// 通知不要生成了
	close(done)

	log.Println("结束")
}

// 多个goroutine
func demo1(done chan struct{}) chan int {
	ch := make(chan int, 20)
	otherDone := make(chan struct{})
	// 这里源源不断放入
	// 只要读取完一个就放入
	go func(ci chan int) {
	Lable:
		for {
			select {
			case ci <- <-demoAGo(otherDone):
			case ci <- <-demoBGo(otherDone):
			case <-done:
				otherDone <- struct{}{}
				otherDone <- struct{}{}

				break Lable
			}
		}

		close(ci)
	}(ch)

	return ch
}

func demoAGo(done chan struct{}) chan int {
	ch := make(chan int, 10)

	go func(ci chan int) {
	Lable:
		for {
			select {
			case ci <- rand.Int():
			case <-done:
				break Lable
			}

		}
		close(ci)
	}(ch)

	return ch
}

func demoBGo(done chan struct{}) chan int {
	ch := make(chan int, 10)

	go func(ci chan int) {
	Lable:
		for {
			select {
			case ci <- rand.Int():
			case <-done:
				break Lable
			}

		}
		close(ci)
	}(ch)

	return ch
}
